﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace OpenLightGroup.Common.Behaviors
{
    /// <summary>
    /// Jumps to the first item in Selector control, that starts with the key that is pressed.
    /// </summary>
    [Description("Jumps to the first item in Selector control, that starts with the key that is pressed.")]
    public class JumpToValueBehavior
        : Behavior<Selector>
    {

        /// <summary>
        /// The name of the property on the item in the list.
        /// </summary>
        public string JumpToPropertyName { get; set; }

        /// <summary>
        /// Specify if the comparison is case sensitive when finding the first item.
        /// </summary>
        public bool IsJumpToValueCaseSensitive { get; set; }


        /// <summary>
        /// Wires up the TextInput event handler.
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();

            this.AssociatedObject.TextInput += new TextCompositionEventHandler(AssociatedObject_TextInput);
        }


        /// <summary>
        /// Removes the event handler from the TextInput event.
        /// </summary>
        protected override void OnDetaching()
        {
            base.OnDetaching();

            this.AssociatedObject.TextInput -= AssociatedObject_TextInput;

        }

        /// <summary>
        /// Handles the TextInput event of the AssociatedObject. This is where the items are enumerated and compared to the last key stroke.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AssociatedObject_TextInput(object sender, TextCompositionEventArgs e)
        {
            //ToDo collect keystrokes and combine them to allow for multiple letters
            if (!string.IsNullOrEmpty(this.JumpToPropertyName))
            {
                string keyValue = e.Text;

                if (!string.IsNullOrEmpty(keyValue))
                {

                    var items = from object i in this.AssociatedObject.Items
                                where i != null && CompareJumpToValue(i.GetType()
                                    .GetProperty(this.JumpToPropertyName)
                                    .GetValue(i, null).ToString(), keyValue)
                                select i;

                    object firstItem = items.FirstOrDefault();

                    if (firstItem != null)
                    {
                        this.AssociatedObject.SelectedItem = firstItem;
                    }


                }

                e.Handled = true;
            }
        }

        /// <summary>
        /// Handles the comparison of the item value and the key stroke
        /// </summary>
        /// <param name="itemValue">Value of the JumpToPropertyName of the item</param>
        /// <param name="textInput">Key that was pressed</param>
        /// <returns></returns>
        protected bool CompareJumpToValue(string itemValue, string textInput)
        {

            bool result = false;

            if (!String.IsNullOrEmpty(itemValue) && !String.IsNullOrWhiteSpace(itemValue))
            {
                if (this.IsJumpToValueCaseSensitive)
                {
                    result = itemValue.StartsWith(textInput, StringComparison.Ordinal);
                }
                else
                {
                    result = itemValue.StartsWith(textInput, StringComparison.OrdinalIgnoreCase);
                }
            }

            return result;
        }
    }
}
